package mmpathgen.controlflowanalysis;

import java.util.Iterator;

import soot.Body;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.toolkits.graph.TrapUnitGraph;
import soot.toolkits.graph.UnitGraph;

/*
 * Construct the control flow graph for a certain method
 */

public class CFGGenByTrapUnitGraph {

	public final static int DANGLING = 0;
	public final static int HIERARCHY = 1;
	public final static int SIGNATURES = 2;
	public final static int BODIES = 3;

	public static void main(String[] args) {
		String packageName = "basicblock";
		String className = "Try_Catch";
		String methodName = "main";

		UnitGraph g = cfgGen(packageName + "." + className, methodName);
		ControlFlowAnalysis.printCFGAsDot(g, packageName + "." + className, methodName);
	}

	/**
	 * @param className
	 * @param methodName
	 */
	public static UnitGraph cfgGen(String className, String methodName) {

		System.out.println("[Control Flow Graph]");

		// Set up the class we're working with
		SootClass c = Scene.v().loadClassAndSupport(className);
		c.setApplicationClass();
		Scene.v().loadNecessaryClasses();

		c.checkLevel(SIGNATURES);
		boolean found = false;
		SootMethod foundMethod = null;

		Iterator<SootMethod> methodIt = c.methodIterator();

		while (methodIt.hasNext()) {
			SootMethod method = methodIt.next();

			if (method.getName().equals(methodName)) {
					found = true;
					foundMethod = method;
					break;
				}
			}

		if (found) {
			// Retrieve the method and its body
			SootMethod m = foundMethod;
			Body b = m.retrieveActiveBody();

			System.out.println("  |- will treat " + className + "."
					+ methodName);
			// Build the CFG and run the analysis
			UnitGraph g = new TrapUnitGraph(b);

			return g;
		} else {
			throw new RuntimeException("couldn't find method " + className
					+ "." + methodName);
		}
	}
}
